From a832734a51de745579281ad17a774744cc62c3c1 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Mon, 7 May 2007 08:52:12 -0600 Subject: [PATCH] [IA64] Create Xen machine vector This allows us to easily switch between hardware or software iommu and simple remapping. The Xen machine vector is only intended for domU guests at this point. Signed-off-by: Alex Williamson --- linux-2.6-xen-sparse/arch/ia64/Kconfig | 4 + linux-2.6-xen-sparse/arch/ia64/Makefile | 1 + linux-2.6-xen-sparse/arch/ia64/kernel/acpi.c | 6 + linux-2.6-xen-sparse/arch/ia64/xen/machvec.c | 4 + linux-2.6-xen-sparse/arch/ia64/xen/xen_dma.c | 145 ++++++++++++++++++ .../include/asm-ia64/machvec.h | 2 + .../include/asm-ia64/machvec_xen.h | 37 +++++ 7 files changed, 199 insertions(+) create mode 100644 linux-2.6-xen-sparse/arch/ia64/xen/machvec.c create mode 100644 linux-2.6-xen-sparse/arch/ia64/xen/xen_dma.c create mode 100644 linux-2.6-xen-sparse/include/asm-ia64/machvec_xen.h diff --git a/linux-2.6-xen-sparse/arch/ia64/Kconfig b/linux-2.6-xen-sparse/arch/ia64/Kconfig index e665b7c391..4991dd4a2b 100644 --- a/linux-2.6-xen-sparse/arch/ia64/Kconfig +++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig @@ -161,6 +161,10 @@ config IA64_SGI_SN2 config IA64_HP_SIM bool "Ski-simulator" +config IA64_XEN + bool "Xen guest" + depends on XEN + endchoice choice diff --git a/linux-2.6-xen-sparse/arch/ia64/Makefile b/linux-2.6-xen-sparse/arch/ia64/Makefile index 399209be32..9c7c05626b 100644 --- a/linux-2.6-xen-sparse/arch/ia64/Makefile +++ b/linux-2.6-xen-sparse/arch/ia64/Makefile @@ -60,6 +60,7 @@ core-$(CONFIG_IA64_DIG) += arch/ia64/dig/ core-$(CONFIG_IA64_GENERIC) += arch/ia64/dig/ core-$(CONFIG_IA64_HP_ZX1) += arch/ia64/dig/ core-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/dig/ +core-$(CONFIG_IA64_XEN) += arch/ia64/dig/ core-$(CONFIG_IA64_SGI_SN2) += arch/ia64/sn/ core-$(CONFIG_XEN) += arch/ia64/xen/ diff --git a/linux-2.6-xen-sparse/arch/ia64/kernel/acpi.c b/linux-2.6-xen-sparse/arch/ia64/kernel/acpi.c index 0176556aee..54e2fb8ab7 100644 --- a/linux-2.6-xen-sparse/arch/ia64/kernel/acpi.c +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/acpi.c @@ -109,6 +109,10 @@ const char *acpi_get_sysname(void) return "hpzx1"; } else if (!strcmp(hdr->oem_id, "SGI")) { return "sn2"; +#ifdef CONFIG_XEN + } else if (is_running_on_xen() && !strcmp(hdr->oem_id, "XEN")) { + return "xen"; +#endif } return "dig"; @@ -123,6 +127,8 @@ const char *acpi_get_sysname(void) return "sn2"; # elif defined (CONFIG_IA64_DIG) return "dig"; +# elif defined (CONFIG_IA64_XEN) + return "xen"; # else # error Unknown platform. Fix acpi.c. # endif diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/machvec.c b/linux-2.6-xen-sparse/arch/ia64/xen/machvec.c new file mode 100644 index 0000000000..4ad588a7c2 --- /dev/null +++ b/linux-2.6-xen-sparse/arch/ia64/xen/machvec.c @@ -0,0 +1,4 @@ +#define MACHVEC_PLATFORM_NAME xen +#define MACHVEC_PLATFORM_HEADER +#include + diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/xen_dma.c b/linux-2.6-xen-sparse/arch/ia64/xen/xen_dma.c new file mode 100644 index 0000000000..5962e73aa6 --- /dev/null +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xen_dma.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2007 Hewlett-Packard Development Company, L.P. + * Alex Williamson + * + * Basic DMA mapping services for Xen guests. + * Based on arch/i386/kernel/pci-dma-xen.c. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include + +#define IOMMU_BUG_ON(test) \ +do { \ + if (unlikely(test)) { \ + printk(KERN_ALERT "Fatal DMA error!\n"); \ + BUG(); \ + } \ +} while (0) + + +/* + * This should be broken out of swiotlb and put in a common place + * when merged with upstream Linux. + */ +static inline int +address_needs_mapping(struct device *hwdev, dma_addr_t addr) +{ + dma_addr_t mask = 0xffffffff; + + /* If the device has a mask, use it, otherwise default to 32 bits */ + if (hwdev && hwdev->dma_mask) + mask = *hwdev->dma_mask; + return (addr & ~mask) != 0; +} + +int +xen_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, + int direction) +{ + int i; + + for (i = 0 ; i < nents ; i++) { + sg[i].dma_address = page_to_bus(sg[i].page) + sg[i].offset; + sg[i].dma_length = sg[i].length; + + IOMMU_BUG_ON(address_needs_mapping(hwdev, sg[i].dma_address)); + } + + return nents; +} +EXPORT_SYMBOL(xen_map_sg); + +void +xen_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, + int direction) +{ +} +EXPORT_SYMBOL(xen_unmap_sg); + +int +xen_dma_mapping_error(dma_addr_t dma_addr) +{ + return 0; +} +EXPORT_SYMBOL(xen_dma_mapping_error); + +int +xen_dma_supported(struct device *dev, u64 mask) +{ + return 1; +} +EXPORT_SYMBOL(xen_dma_supported); + +void * +xen_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp) +{ + unsigned long vaddr; + unsigned int order = get_order(size); + + vaddr = __get_free_pages(gfp, order); + + if (!vaddr) + return NULL; + + if (xen_create_contiguous_region(vaddr, order, + dev->coherent_dma_mask)) { + free_pages(vaddr, order); + return NULL; + } + + memset((void *)vaddr, 0, size); + *dma_handle = virt_to_bus((void *)vaddr); + + return (void *)vaddr; +} +EXPORT_SYMBOL(xen_alloc_coherent); + +void +xen_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + unsigned int order = get_order(size); + + xen_destroy_contiguous_region((unsigned long)vaddr, order); + free_pages((unsigned long)vaddr, order); +} +EXPORT_SYMBOL(xen_free_coherent); + +dma_addr_t +xen_map_single(struct device *dev, void *ptr, size_t size, + int direction) +{ + dma_addr_t dma_addr = virt_to_bus(ptr); + + IOMMU_BUG_ON(range_straddles_page_boundary(ptr, size)); + IOMMU_BUG_ON(address_needs_mapping(dev, dma_addr)); + + return dma_addr; +} +EXPORT_SYMBOL(xen_map_single); + +void +xen_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, + int direction) +{ +} +EXPORT_SYMBOL(xen_unmap_single); diff --git a/linux-2.6-xen-sparse/include/asm-ia64/machvec.h b/linux-2.6-xen-sparse/include/asm-ia64/machvec.h index 15b545a897..e712d90b19 100644 --- a/linux-2.6-xen-sparse/include/asm-ia64/machvec.h +++ b/linux-2.6-xen-sparse/include/asm-ia64/machvec.h @@ -108,6 +108,8 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *); # include # elif defined (CONFIG_IA64_SGI_SN2) # include +# elif defined (CONFIG_IA64_XEN) +# include # elif defined (CONFIG_IA64_GENERIC) # ifdef MACHVEC_PLATFORM_HEADER diff --git a/linux-2.6-xen-sparse/include/asm-ia64/machvec_xen.h b/linux-2.6-xen-sparse/include/asm-ia64/machvec_xen.h new file mode 100644 index 0000000000..cdffdfba53 --- /dev/null +++ b/linux-2.6-xen-sparse/include/asm-ia64/machvec_xen.h @@ -0,0 +1,37 @@ +#ifndef _ASM_IA64_MACHVEC_XEN_h +#define _ASM_IA64_MACHVEC_XEN_h + +extern ia64_mv_setup_t dig_setup; +extern ia64_mv_dma_alloc_coherent xen_alloc_coherent; +extern ia64_mv_dma_free_coherent xen_free_coherent; +extern ia64_mv_dma_map_single xen_map_single; +extern ia64_mv_dma_unmap_single xen_unmap_single; +extern ia64_mv_dma_map_sg xen_map_sg; +extern ia64_mv_dma_unmap_sg xen_unmap_sg; +extern ia64_mv_dma_supported xen_dma_supported; +extern ia64_mv_dma_mapping_error xen_dma_mapping_error; + +/* + * This stuff has dual use! + * + * For a generic kernel, the macros are used to initialize the + * platform's machvec structure. When compiling a non-generic kernel, + * the macros are used directly. + */ +#define platform_name "xen" +#define platform_setup dig_setup +#define platform_dma_init machvec_noop +#define platform_dma_alloc_coherent xen_alloc_coherent +#define platform_dma_free_coherent xen_free_coherent +#define platform_dma_map_single xen_map_single +#define platform_dma_unmap_single xen_unmap_single +#define platform_dma_map_sg xen_map_sg +#define platform_dma_unmap_sg xen_unmap_sg +#define platform_dma_sync_single_for_cpu machvec_dma_sync_single +#define platform_dma_sync_sg_for_cpu machvec_dma_sync_sg +#define platform_dma_sync_single_for_device machvec_dma_sync_single +#define platform_dma_sync_sg_for_device machvec_dma_sync_sg +#define platform_dma_supported xen_dma_supported +#define platform_dma_mapping_error xen_dma_mapping_error + +#endif /* _ASM_IA64_MACHVEC_XEN_h */ -- 2.30.2